<?php
namespace app\scodetrace\model;

use \app\scodetrace\encoder\ScodeEncoder;
use \app\scodetrace\encoder\TcodeEncoder;

class Scode extends \app\common\model\Base {

	// protected $autoWriteTimestamp='datetime';

	// protected $createTime='create_time';
	// protected $updateTime='create_time';

	protected $table='xl_scode';

	protected $auto=['status' => 1];


  protected $append=['first_time_l', 'scode', 'tcode', 'batch_no','first_query'];

  public function getFirstQueryAttr($val, $data) {
    if ($scodeModel = model('ScodeLog')->get($data['first_log_id'])) {
      return $scodeModel->visible(['location_ip','area','query_time']);
    }
  }

  public function getFirstTimeLAttr($val,$data) {
  	if (isset($data['first_time'])) {
  		return date('Y-m-d h:i:s', $data['first_time']);
  	} else {
  		return null;
  	}
  }

	public function logInfo() {
		return $this->hasMany("ScodeLog");
	}

	public function batch() {
		return $this->belongsTo("Batch");
	}

	private function logOne($time,$place_id,$ip) {
    $logModel=$this->logInfo();
		if ($logModel=$logModel->save([
			'area_id'=>$place_id,
			'create_time'=>$time,
			'location_ip'=>$ip
		])) {
      return $logModel->getAttr('id');
    } else {
      return 0;
    }
	}

	public function logOneTrace($ids,$logText,$area_id,$result) {
    $scodes = $this->field(['id','log_id'])->select($ids);
    if (!$scodes) {
    	return ['ids'=>null,'errmsg'=>'ids错误'];
    }
    $tmp = [];
    foreach ($scodes as &$s) {
      if ($s->log_id) {
        $tmp[$s->log_id][] = $s['id'];
      } else {
        $tmp[0][] = $s['id'];
      }
    }
    $err = [];
    foreach($tmp as $k=>$v) {
      if (($errmsg=$this->_logOneTrace($k,$v,$logText,$area_id,$result))!==true) {
        $err[] = ['ids'=>$v,'errmsg'=>$errmsg];
      }
    }
    return $err;
	}

	private function _logOneTrace($pid,$ids,$logText,$area_id,$result) {
    $logModel=model('TraceLog');
    if ($pid) {
      if ($logData=$logModel->where('id',$pid)->find()) {
        if ($logText==$logData->getAttr('logtext') && $area_id==$logData->getAttr('area_id') && $result == $logData->getAttr('result')) {
          return '请勿反复提交相同的内容';
        }
      } else {
        return "溯源日志表已经被损坏";
      }
    }

    if ($log_id=$logModel::logOne($pid,$logText,$area_id,$result)) {
      $this->where('id',"in",$ids)->update(['log_id'=>$log_id]);
      return true;
    } else {
      return '写入log失败';
    }
    return true;
  }

	public function getQueryTimeAttr($value,$data){
		if ($data['first_time']){
			return date("Y-m-d h:i:s",$data['first_time']);
		} else {
			return null;
		}
	}

	public function getScodeAttr($val,$data){
		return ScodeEncoder::getInstance()->encode($data['id'],$data['company_id']);
	}

	public function getTcodeAttr($val,$data) {
		return TcodeEncoder::getInstance()->encode($data['id']);
	}

	public function getBatchNoAttr() {
		return $this->batch->getAttr('serial_number');
	}

	public function byTcode($val) {
		$tmp = TcodeEncoder::getInstance()->decode($val);
		if ($tmp) {
			return $this->get($tmp);
		}
	}

	public static function check($scode) {
		$id = ScodeEncoder::getInstance()->decode($scode);
		if (!$id) {
			return [
			'found'=>false,
      'first_query'=>null,
			'product'=>null,
			'batch'=>null,
			'queried'=>0,
			'token'=>null,
			];
		}
		$q=Scode::get($id);
		$queried=0;
		$batch=null;				//batch info
		$time=time();				//current time,used for generate token and put timestamp in log.
		$token=null;
    $first_query=null;
    $product=null;
		if ($q) {
			//prevent to check a disable scode
			if ($q->getAttr('status')) {
				$areaModel=model('baseinfo/Area');
				if ($area = $areaModel::byIP($ip = get_client_ip_from_ns(true))) {
					$place_id = $area->id;
				} else {
					$place_id = 0;
				}

				if (!($newid = $q->logOne($time,$place_id,$ip))) {
          // fixme: to log it
        }
				$q->setInc('query_amount');

				if (($queried=$q['query_amount'])==1) {
					$q['first_log_id']=$newid;
					$q->save();
				}
        $first_query=model('scodetrace/ScodeLog')->get($q->getAttr('first_log_id'))->visible(['location_ip','area','query_time']);
				$batch=$q->batch->hidden(['id','site_id','product_id','submitter_id','deleted','submitter_time','product']);
				$token=md5($queried.$scode.'salt');
				cache('SCODETOKEN_'.$token,['scode'=>$scode,'id'=>$q->id,'obj'=>$q],1200);
        if ($batch) {
          $product=$batch->product;
          if ($product) {
            $product=$product->hidden(['id','site_id','product_id','submitter_id','submitter_time']);
        }
    }
			} else {
				$q=false;
			}
		}



		return [
			'found'=>$q?true:false,
      'first_query' => $first_query,
			'product'=>$product,
			'batch'=>$q?$q->batch:null,
			'queried'=>$queried,
			'token'=>$token,
		];
	}

	//page是从1开始编号的
	public function getLog($token,$page=1,$limit=10) {
		$cache=cache('SCODETOKEN_'.$token);
		if ($cache&&($q=$cache['obj'])) {
			return [
				'count'=>$q->logInfo()->count(),
				'offset'=>($page-1)*$limit,
				'data'=>$q->logInfo()->order('create_time','desc')->page($page,$limit)->select()->hidden(['id'])
			];
		}
		$this->error='令牌过期或无效';
		return null;
	}

	public function exportScode($ids,$force = false) {
		$tmp = [];
		$tmp[] = ['id','in',$ids];
		if ($force)
			$tmp[] = ['is_exported','=','1'];
		$codes = $this->where($tmp)->column('id');
		$this->where('id','in',$codes)->update(['is_exported'=>1]);
		return ScodeEncoder::getInstance()->encode($codes,2);
	}

	public function batchCreate($count,$company_id,$batch_id = null) {
		$data=[];
		if (!model('baseinfo/Company')->get($company_id)) {
			$this->error='找不到对应的公司';
			return false;
		}
		if ($batch_id && !model('Batch')->get($batch_id)) {
			$this->error='找不到对应的批次';
			return false;
		}
		for ($i=0;$i<$count;$i++) {
			$data[] = ['company_id'=>$company_id, 'batch_id'=>$batch_id];
		}
		$result=$this->query('call up_batchCreate(:count,:company_id,:batch_id)',[
			'count'=> $count,
			'company_id'=>$company_id,
			'batch_id'=>$batch_id
		]);
		foreach ($result[0] as &$v) {
			$v = $v['id'];
		}
		$result=$result[0];
		if ($result) {
			$result2 = [];
			$s = ScodeEncoder::getInstance()->encode($result,$company_id);
			$t = TcodeEncoder::getInstance()->encode($result);
			$c = count($result);
			for ($i=0;$i<$c;$i++) {
				$result2[]=['scode'=>$s[$i], 'tcode'=>$t[$i]];
			}
			return $result2;
		} else {
			return null;
		}
	}
}

?>